A mixed-content is when a resource is loaded with the HTTP protocol, from a website accessed with the HTTPs protocol, thus mixed-content are not
encrypted and exposed to MITM attacks and could break the entire level of
protection that was desired by implementing encryption with the HTTPs protocol.
The main threat with mixed-content is not only the confidentiality of resources but the whole website integrity:
- A passive mixed-content (eg: <img src="http://example.com/picture.png">) allows an attacker to access and replace only these
resources, like images, with malicious ones that could lead to successful phishing attacks.
- With active mixed-content (eg: <script src="http://example.com/library.js">) an attacker can compromise the entire website by
injecting malicious javascript code for example (accessing and modifying the DOM, steal cookies, etc).
Ask Yourself Whether
- The HTTPS protocol is in place and external resources are fetched from the website pages.
There is a risk if you answered yes to this question.
Recommended Secure Coding Practices
Implement content security policy block-all-mixed-content directive which is supported by all modern browsers and will block loading of
mixed-contents.
Sensitive Code Example
In Express.js application the code is sensitive if the helmet-csp or helmet middleware is used without the blockAllMixedContent
directive:
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
"default-src": ["'self'", 'example.com', 'code.jquery.com']
} // Sensitive: blockAllMixedContent directive is missing
})
);
Compliant Solution
In Express.js application a standard way to block mixed-content is to put in place the helmet-csp or helmet middleware with the
blockAllMixedContent
directive:
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
"default-src": ["'self'", 'example.com', 'code.jquery.com'],
blockAllMixedContent: [] // Compliant
}
})
);
See